﻿'Copyright (c) 2008, William Severance, Jr., WESNet Designs
'All rights reserved.

'Redistribution and use in source and binary forms, with or without modification, are permitted
'provided that the following conditions are met:

'Redistributions of source code must retain the above copyright notice, this list of conditions
'and the following disclaimer.

'Redistributions in binary form must reproduce the above copyright notice, this list of conditions
'and the following disclaimer in the documentation and/or other materials provided with the distribution.

'Neither the name of William Severance, Jr. or WESNet Designs may be used to endorse or promote
'products derived from this software without specific prior written permission.

'Disclaimer: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
'            OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
'            AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE
'            FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
'            LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
'            INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
'            OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
'            IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

'Although I will try to answer questions regarding the installation and use of this software when
'such questions are submitted via e-mail to the below address, no promise of further
'support or enhancement is made nor should be assumed.

'Developer Contact Information:
'     William Severance, Jr.
'     WESNet Designs
'     679 Upper Ridge Road
'     Bridgton, ME 04009
'     Phone: 207-647-9375
'     E-Mail: bill@wesnetdesigns.com
'     Website: www.wesnetdesigns.com


Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.IO
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports DotNetNuke
Imports DotNetNuke.Common
Imports DotNetNuke.Common.Utilities
Imports DotNetNuke.Services.FileSystem
Imports DotNetNuke.Services.Localization
Imports DotNetNuke.Services.Exceptions
Imports DotNetNuke.Security
'Imports System.Runtime.InteropServices
Imports WESNet.Utilities

Namespace WESNet.DNN.Controls.ImageEditorControl

    <DefaultProperty("ImagePath"), ToolboxData("<{0}:ImageEditorControl runat=server />")> _
    <Designer(GetType(WESNet.DNN.Controls.ImageEditorControl.ImageEditorControlDesigner))> _
    Public Class ImageEditorControl
        Inherits System.Web.UI.WebControls.CompositeControl

#Region "Private Members"

        'Controls
        Private pnlUpdate1 As System.Web.UI.UpdatePanel
        Private pnlUpdate2 As System.Web.UI.UpdatePanel
        Private btnEditMode As System.Web.UI.WebControls.ImageButton
        Private imgView As System.Web.UI.WebControls.Image
        Private imgEditor As New WESNet.AJAX.Controls.ImageEditor.ImageEditor

        Private imgStorageLocationIcon As System.Web.UI.WebControls.Image
        Private lblFolder As System.Web.UI.HtmlControls.HtmlGenericControl
        Private ddlFolders As System.Web.UI.WebControls.DropDownList

        Private lblFile As System.Web.UI.HtmlControls.HtmlGenericControl
        Private ddlFiles As System.Web.UI.WebControls.DropDownList

        Private lblUpload As System.Web.UI.HtmlControls.HtmlGenericControl
        Private fileUpload As System.Web.UI.WebControls.FileUpload

        Private lblSaveAs As System.Web.UI.HtmlControls.HtmlGenericControl
        Private tbSaveAs As System.Web.UI.WebControls.TextBox

        Private btnCmd1 As System.Web.UI.WebControls.LinkButton
        Private btnCmd2 As System.Web.UI.WebControls.LinkButton
        Private btnUpload As System.Web.UI.WebControls.LinkButton
        Private btnCancel As System.Web.UI.WebControls.LinkButton

        Private lblError As System.Web.UI.WebControls.Label

        'Variables
        Private _EditMode As DotNetNuke.UI.WebControls.PropertyEditorMode = DotNetNuke.UI.WebControls.PropertyEditorMode.View
        Private _ModuleId As Integer = -2
        Private _IsEditable As Integer = 0
        Private _Portal As Entities.Portals.PortalInfo
        Private _LocalResourceFile As String = ""
        Private _Thumb As System.Drawing.Bitmap
        Private _PostedFile As System.Web.HttpPostedFile
        Private _ThumbFileLength As Integer
        Private imgViewFileLength As Integer
        Private _ParentPath As String
        Private _FolderList As Generic.Dictionary(Of String, DotNetNuke.Services.FileSystem.FolderInfo)
        Private _FileList As Generic.Dictionary(Of String, DotNetNuke.Services.FileSystem.FileInfo)
        Private _SameAsOriginal As String = "[Same As Original]"
        Private _UseOctreeQuantizer As Boolean = True

#End Region

#Region "Public Properties"

        <Description("When true shows edit pencil or return button to allow user to switch " & _
                      "between EditMode and ViewMode"), DefaultValue(True)> _
        Public Property AllowModeSwitch() As Boolean
            Get
                Return GetPropertyValue("AllowModeSwitch", True)
            End Get
            Set(ByVal value As Boolean)
                SetPropertyValue("AllowModeSwitch", value)
            End Set
        End Property

        <Description("Determines if control is in EditMode or ViewMode. Property is persisted in ClientState")> _
        <DefaultValue(GetType(DotNetNuke.UI.WebControls.PropertyEditorMode), "View")> _
        Public Property EditMode() As DotNetNuke.UI.WebControls.PropertyEditorMode
            Get
                Return _EditMode
            End Get
            Set(ByVal value As DotNetNuke.UI.WebControls.PropertyEditorMode)
                If _EditMode <> value Then
                    _EditMode = value

                    'Force recreation of child controls on change in edit mode
                    ChildControlsCreated = False
                    EnsureChildControls()
                End If
            End Set
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property PortalSettings() As Entities.Portals.PortalSettings
            Get
                Return Entities.Portals.PortalController.GetCurrentPortalSettings
            End Get
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Property ModuleID() As Integer
            Get
                If _ModuleId = -2 Then
                    If Not ViewState("ModuleId") Is Nothing Then
                        _ModuleId = Convert.ToInt32(ViewState("ModuleId"))
                    Else
                        If Not Page.Request.QueryString("mid") Is Nothing Then
                            _ModuleId = Int32.Parse(Page.Request.QueryString("mid"))
                        End If
                    End If
                End If
                Return _ModuleId
            End Get
            Set(ByVal value As Integer)
                SetPropertyValue("ModuleId", value)
            End Set
        End Property

        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property IsEditable() As Boolean
            Get
                ' Perform tri-state switch check to avoid having to perform a security
                ' role lookup on every property access (instead caching the result)
                If _IsEditable = 0 Then
                    Dim blnPreview As Boolean = (PortalSettings.UserMode = Entities.Portals.PortalSettings.Mode.View)
                    If PortalSettings.ActiveTab.ParentId = PortalSettings.AdminTabId Or PortalSettings.ActiveTab.ParentId = PortalSettings.SuperTabId Then
                        blnPreview = False
                    End If

                    Dim blnHasModuleEditPermissions As Boolean = False
                    If Not ModuleID = -1 Then
                        blnHasModuleEditPermissions = Permissions.ModulePermissionController.HasModulePermission(ModuleID, PortalSettings.ActiveTab.TabID, "EDIT") OrElse _
                            PortalSecurity.IsInRoles(PortalSettings.ActiveTab.AdministratorRoles) OrElse _
                            PortalSecurity.IsInRoles(PortalSettings.AdministratorRoleName)
                    End If

                    If (Not blnPreview) And blnHasModuleEditPermissions Then
                        _IsEditable = 1
                    Else
                        _IsEditable = 2
                    End If
                End If
                Return _IsEditable = 1
            End Get
        End Property

        <Description("True if the editor contains a modified image or uploaded file that has not been saved")> _
        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Property IsDirty() As Boolean
            Get
                EnsureChildControls()
                Return imgEditor.IsDirty
            End Get
            Set(ByVal value As Boolean)
                EnsureChildControls()
                imgEditor.IsDirty = value
            End Set
        End Property

        <Description("The LocalResourceFile from which localization values will be obtained")> _
        Public Property LocalResourceFile() As String
            Get
                If _LocalResourceFile.Length = 0 Then
                    '_LocalResourceFile = ModulePath & Localization.LocalResourceDirectory & "/WESNet_ImageEditorControl.ascx"
                    _LocalResourceFile = "controls/" & Localization.LocalResourceDirectory & "/WESNet_ImageEditorControl.ascx"
                End If
                Return _LocalResourceFile
            End Get
            Set(ByVal Value As String)
                _LocalResourceFile = Value
            End Set
        End Property

        <Description("When true will enable selection from a list of image files"), DefaultValue(True)> _
        Public Property AllowFileOpen() As Boolean
            Get
                EnsureChildControls()
                Return imgEditor.AllowFileOpen
            End Get
            Set(ByVal value As Boolean)
                EnsureChildControls()
                imgEditor.AllowFileOpen = value
                ChildControlsCreated = False
            End Set
        End Property

        <Description("When true will enable image file uploading"), DefaultValue(True)> _
        Public Property AllowFileUpload() As Boolean
            Get
                EnsureChildControls()
                Return imgEditor.AllowFileUpload
            End Get
            Set(ByVal value As Boolean)
                EnsureChildControls()
                imgEditor.AllowFileUpload = value
                ChildControlsCreated = False
            End Set
        End Property

        <Description("When true will enable saving uploaded or modified image to storage"), DefaultValue(True)> _
        Public Property AllowFileSave() As Boolean
            Get
                EnsureChildControls()
                Return imgEditor.AllowFileSave
            End Get
            Set(ByVal value As Boolean)
                EnsureChildControls()
                imgEditor.AllowFileSave = value
                ChildControlsCreated = False
            End Set
        End Property

        <Description("When true will permit specification of a Save As filename when saving image"), DefaultValue(False)> _
        Public Property AllowFileSaveAs() As Boolean
            Get
                Return GetPropertyValue("AllowFileSaveAs", False)
            End Get
            Set(ByVal value As Boolean)
                SetPropertyValue("AllowFileSaveAs", value)
                ChildControlsCreated = False
            End Set
        End Property

        <Description("The caption that will appear at the top of the image editor control"), DefaultValue("")> _
        Public Property Caption() As String
            Get
                EnsureChildControls()
                Return imgEditor.Caption
            End Get
            Set(ByVal value As String)
                EnsureChildControls()
                imgEditor.Caption = value
            End Set
        End Property

        <Description("Size of the image when in View mode."), TypeConverter(GetType(System.Drawing.SizeConverter)), _
         DefaultValue("")> _
        Public Property ViewSize() As System.Drawing.Size
            Get
                Return GetPropertyValue("ViewSize", Defaults.ViewSize)
            End Get
            Set(ByVal value As System.Drawing.Size)
                SetPropertyValue("ViewSize", value)
            End Set
        End Property

        <Description("Size of the editor preview image when in Edit mode."), TypeConverter(GetType(System.Drawing.SizeConverter)), _
         DefaultValue("400,300")> _
        Public Property PreviewSize() As System.Drawing.Size
            Get
                EnsureChildControls()
                Return imgEditor.PreviewSize
            End Get
            Set(ByVal value As System.Drawing.Size)
                EnsureChildControls()
                imgEditor.PreviewSize = value
            End Set
        End Property

        <Description("Time for which working image data is cached in memory")> _
        <DefaultValue(Defaults.CacheTime)> _
        Public Property CacheTime() As Double
            Get
                EnsureChildControls()
                Return imgEditor.CacheTime
            End Get
            Set(ByVal value As Double)
                EnsureChildControls()
                imgEditor.CacheTime = value
            End Set
        End Property

        <Description("The unique GUID used to identify working image data in the cache")> _
        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property ImageGuid() As String
            Get
                EnsureChildControls()
                Return imgEditor.ImageGuid
            End Get
        End Property

        <Description("Permitted image file extensions (without periods) for opening and uploading as comma delimited string")> _
        <DefaultValue(Defaults.FileFilter)> _
        Public Property FileFilter() As String
            Get
                Return GetPropertyValue("FileFilter", Defaults.FileFilter)
            End Get
            Set(ByVal Value As String)
                SetPropertyValue("FileFilter", Value.ToLower)
                If EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.Edit Then
                    If Not Folder Is Nothing Then BindFiles()
                End If
            End Set
        End Property

        <Description("Automatically resize image on upload to MaxImageSize if true"), DefaultValue(True), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
        Public Property AutoResize() As Boolean
            Get
                Return GetPropertyValue("AutoResize", True)
            End Get
            Set(ByVal Value As Boolean)
                SetPropertyValue("AutoResize", Value)
            End Set
        End Property

        <Description("Image size when autoresizing. If LockAspect = True then image will maintain aspect " & _
                        "be constrained by this size"), TypeConverter(GetType(System.Drawing.SizeConverter)), DefaultValue("")> _
        Public Property MaxImageSize() As System.Drawing.Size
            Get
                Return GetPropertyValue("MaxImageSize", Defaults.MaxImageSize)
            End Get
            Set(ByVal value As System.Drawing.Size)
                SetPropertyValue("MaxImageSize", value)
            End Set
        End Property

        <Description("Lock aspect ratio when resizing if true"), DefaultValue(True), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
        Public Property LockAspect() As Boolean
            Get
                Return GetPropertyValue("LockAspect", True)
            End Get
            Set(ByVal Value As Boolean)
                SetPropertyValue("LockAspect", Value)
            End Set
        End Property

        <Description("Maximum magnification factor when resizing"), DefaultValue(Defaults.MaxMagnification), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
        Public Property MaxMagnification() As Single
            Get
                Return GetPropertyValue("MaxMagnification", Defaults.MaxMagnification)
            End Get
            Set(ByVal Value As Single)
                SetPropertyValue("MaxMagnification", Value)
            End Set
        End Property

        <Description("JPEG image encoding quality (0-100) for saved images"), DefaultValue(Defaults.Quality), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
            Public Property Quality() As Long
            Get
                Return GetPropertyValue("Quality", Defaults.Quality)
            End Get
            Set(ByVal Value As Long)
                SetPropertyValue("Quality", Value)
            End Set
        End Property

        <Description("When true use the Octree Quantizer for GIF image palete optimization. " & _
                     "Note this property is not persisted in Viewstate"), DefaultValue(True), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)> _
         Public Property UseOctreeQuantizer() As Boolean
            Get
                Return _UseOctreeQuantizer
            End Get
            Set(ByVal value As Boolean)
                _UseOctreeQuantizer = value
            End Set
        End Property

        'Public Property Required() As Boolean
        '    Get
        '        Return GetPropertyValue("Required", False)
        '    End Get
        '    Set(ByVal Value As Boolean)
        '        SetPropertyValue("Required", Value)
        '    End Set
        'End Property

        <Description("When true, a dropdown list of folders available to the current user will be displayed " & _
                       "when selecting an image file"), DefaultValue(True)> _
        Public Property ShowFolders() As Boolean
            Get
                Return (AllowFileOpen Or AllowFileSave) AndAlso GetPropertyValue("ShowFolders", True)
            End Get
            Set(ByVal value As Boolean)
                SetPropertyValue("ShowFolders", value)
                If EditorCreated Then
                    ChildControlsCreated = False
                    EnsureChildControls()
                    If value Then BindFolders()
                End If
            End Set
        End Property

        <Description("When true, a dropdown list of files in the currently selected Folder will be displayed " & _
                       "when selecting an image file"), DefaultValue(True)> _
        Public Property ShowFiles() As Boolean
            Get
                Return AllowFileOpen AndAlso GetPropertyValue("ShowFiles", True)
            End Get
            Set(ByVal Value As Boolean)
                SetPropertyValue("ShowFiles", Value)
                If EditorCreated Then
                    ChildControlsCreated = False
                    EnsureChildControls()
                    If Value Then BindFiles()
                End If
            End Set
        End Property

        <Description("When true, secure folders available to the current user will be included in the list of folders")> _
        <DefaultValue(True)> _
        Public Property ShowSecure() As Boolean
            Get
                Return ShowFolders AndAlso GetPropertyValue("ShowSecure", True)
            End Get
            Set(ByVal Value As Boolean)
                SetPropertyValue("ShowSecure", Value)
                If EditorCreated And ShowFolders Then
                    BindFolders()
                End If
            End Set
        End Property

        <Description("When true, database folders available to the current user will be included in the list of folders")> _
        <DefaultValue(True)> _
        Public Property ShowDatabase() As Boolean
            Get
                Return ShowFolders AndAlso GetPropertyValue("ShowDatabase", True)
            End Get
            Set(ByVal value As Boolean)
                SetPropertyValue("ShowDatabase", value)
                If EditorCreated And ShowFolders Then
                    BindFolders()
                End If
            End Set
        End Property

        <Description("When true, thumbnail images (those having thumbnail suffix) will be shown in file list")> _
        <DefaultValue(False)> _
        Public Property ShowThumbs() As Boolean
            Get
                Return ShowFiles AndAlso GetPropertyValue("ShowThumbs", False)
            End Get
            Set(ByVal value As Boolean)
                SetPropertyValue("ShowThumbs", value)
                If EditorCreated And ShowFiles Then
                    BindFiles()
                End If
            End Set
        End Property

        <Description("Returns the directory root - either Portals/_default/ or Portals/(PortalID)/")> _
        <Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property Root() As String
            Get
                If IsHostMenu Then
                    Return Common.Globals.HostPath & "/"
                Else
                    Return Portal.HomeDirectory & "/"
                End If
            End Get
        End Property

        <Description("Complete parent folder path for host or portal including the trailing slash"), Browsable(False), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
         Public ReadOnly Property ParentPath() As String
            Get
                If _ParentPath Is Nothing AndAlso Not DesignMode Then
                    If IsHostMenu Then
                        _ParentPath = Common.Globals.HostMapPath()
                    Else
                        _ParentPath = Portal.HomeDirectoryMapPath()
                    End If
                End If
                Return _ParentPath
            End Get
        End Property

        <Description("Partial folder path - referenced from ../Portals/(PortalID)/")> _
        Public Property Folder() As String
            Get
                Return GetPropertyValue("Folder", String.Empty)
            End Get
            Set(ByVal Value As String)
                SetPropertyValue("Folder", Value)
            End Set
        End Property

        <Description("DNN FolderID"), Browsable(False)> _
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Property FolderID() As Integer
            Get
                Return GetPropertyValue("FolderID", -1)
            End Get
            Set(ByVal value As Integer)
                SetPropertyValue("FolderID", value)
            End Set
        End Property

        <Description("Filename with extension")> _
        Public Property FileName() As String
            Get
                Return GetPropertyValue("Filename", "")
            End Get
            Set(ByVal Value As String)
                SetPropertyValue("Filename", Value)
            End Set
        End Property

        <Description("DNN FileID of the image file"), Browsable(False)> _
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Property FileID() As Integer
            Get
                Return GetPropertyValue("FileID", -1)
            End Get
            Set(ByVal Value As Integer)
                SetPropertyValue("FileID", Value)
            End Set
        End Property

        <Description("File path - referenced from ..(Root)/FolderPath/Filename.Ext")> _
         Public Property FilePath() As String
            Get
                Return Path.Combine(Folder, FileName).Replace("\", "/")
            End Get
            Set(ByVal Value As String)
                If String.IsNullOrEmpty(Value) Then Value = Root
                Folder = FileSystemUtils.FormatFolderPath(Path.GetDirectoryName(Value).Replace("\", "/"))
                FileName = Path.GetFileName(Value)
                FolderID = GetFolderIDFromName(Folder)
                FileID = GetFileIDFromName(FileName)
                ThumbFileID = GetFileIDFromName(ThumbFileName)
            End Set
        End Property

        <Description("Filename to which a new or modified file will be saved")> _
        Public Property SaveAsFilename() As String
            Get
                If AllowFileSaveAs AndAlso EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.Edit AndAlso ChildControlsCreated Then
                    Return tbSaveAs.Text
                Else
                    Return GetPropertyValue("SaveAsFilename", _SameAsOriginal)
                End If
            End Get
            Set(ByVal Value As String)
                If AllowFileSaveAs AndAlso EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.Edit Then
                    EnsureChildControls()
                    tbSaveAs.Text = Value
                End If
                SetPropertyValue("SaveAsFileName", Value)
            End Set
        End Property

        <Description("Automatically create thumbnail if true"), DefaultValue(True)> _
        Public Property AutoThumbnail() As Boolean
            Get
                Return GetPropertyValue("AutoThumbnail", True)
            End Get
            Set(ByVal Value As Boolean)
                SetPropertyValue("AutoThumbnail", Value)
            End Set
        End Property

        <Description("Thumb size when autothumbnailing. If LockAspect = True then thumb will maintain aspect " & _
                        "be constrained by this size"), TypeConverter(GetType(System.Drawing.SizeConverter)), DefaultValue("")> _
        Public Property MaxThumbSize() As System.Drawing.Size
            Get
                Return GetPropertyValue("MaxThumbSize", Defaults.MaxThumbSize)
            End Get
            Set(ByVal value As System.Drawing.Size)
                SetPropertyValue("MaxThumbSize", value)
            End Set
        End Property

        <Description("Suffix appended to filename when autothumbnailing"), DefaultValue(Defaults.ThumbSuffix)> _
        Public Property ThumbSuffix() As String
            Get
                Return GetPropertyValue("ThumbSuffix", Defaults.ThumbSuffix)
            End Get
            Set(ByVal value As String)
                SetPropertyValue("ThumbSuffix", value)
            End Set
        End Property

        <Description("Thumbnail filename")> _
        Public Property ThumbFileName() As String
            Get
                If ViewState("ThumbFilename") Is Nothing Then
                    If String.IsNullOrEmpty(FileName) Then
                        Return String.Empty
                    Else
                        Return Utilities.InsertFileSuffix(FileName, ThumbSuffix)
                    End If
                Else
                    Return CType(ViewState("ThumbFilename"), String)
                End If
            End Get
            Set(ByVal Value As String)
                SetPropertyValue("ThumbFilename", Value)
            End Set
        End Property

        <Description("Thumbnail file path - referenced from ../Portals/(PortalID)/FolderPath/Filename.Ext")> _
        Public Property ThumbPath() As String
            Get
                Return Path.Combine(Folder, ThumbFileName).Replace("\", "/")
            End Get
            Set(ByVal Value As String)
                If String.IsNullOrEmpty(Value) Then Value = Root
                Folder = FileSystemUtils.FormatFolderPath(Path.GetDirectoryName(Value).Replace("\", "/"))
                ThumbFileName = Path.GetFileName(Value)
                FolderID = GetFolderIDFromName(Folder)
                ThumbFileID = GetFileIDFromName(ThumbFileName)
            End Set
        End Property

        <Description("DNN FileID of the thumb file")> _
         Public Property ThumbFileID() As Integer
            Get
                Return GetPropertyValue("ThumbFileID", -1)
            End Get
            Set(ByVal Value As Integer)
                SetPropertyValue("ThumbFileID", Value)
            End Set
        End Property

        <Description("Provides access to the underlying HttpPostedFile following an upload"), _
         Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Property PostedFile() As System.Web.HttpPostedFile
            Get
                If _PostedFile Is Nothing And Not DesignMode Then
                    Dim obj As Object = DataCache.GetCache("HPF:" & ImageGuid)
                    If Not obj Is Nothing Then
                        _PostedFile = CType(obj, System.Web.HttpPostedFile)
                    Else
                        If AllowFileUpload And fileUpload.FileName <> String.Empty Then
                            _PostedFile = fileUpload.PostedFile
                            If Not _PostedFile Is Nothing Then DataCache.SetCache("HPF:" & ImageGuid, _PostedFile, Nothing, DateTime.MaxValue, TimeSpan.FromSeconds(CacheTime))
                        End If
                    End If
                End If
                Return _PostedFile
            End Get
            Set(ByVal Value As System.Web.HttpPostedFile)
                If Value Is Nothing Then
                    DataCache.RemoveCache("HPF:" & ImageGuid)
                Else
                    DataCache.SetCache("HPF:" & ImageGuid, Value, Nothing, DateTime.MaxValue, TimeSpan.FromSeconds(CacheTime))
                End If
                _PostedFile = Value
            End Set
        End Property

        <Description("Size of last image upload in bytes"), Browsable(False), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property UploadLength() As Int32
            Get
                If PostedFile Is Nothing Then
                    Return 0
                Else
                    Return PostedFile.ContentLength
                End If
            End Get
        End Property

        <Description("Content type (MIME) of last image upload"), Browsable(False), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property UploadType() As String
            Get
                If PostedFile Is Nothing Then
                    Return String.Empty
                Else
                    Return PostedFile.ContentType
                End If
            End Get
        End Property

        <Description("Filename with extension of last image upload"), Browsable(False), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public ReadOnly Property UploadFilename() As String
            Get
                If PostedFile Is Nothing Then
                    Return String.Empty
                Else
                    Return Path.GetFileName(PostedFile.FileName)
                End If
            End Get
        End Property

        <Description("Returns true if image file has been uploaded"), Browsable(False), _
         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
         Public ReadOnly Property HasUpload() As Boolean
            Get
                Return Not fileUpload Is Nothing AndAlso fileUpload.HasFile
            End Get
        End Property

        'The following property code is untested at this time and should be used with caution
        <Description("Filepath url in the form of 'FileID=nnnn' where nnnn is a valid DNN FileID or else the Filepath")> _
        Public Property Url() As String
            Get
                Dim fid As Integer = FileID
                If FileID = -1 Then
                    If ShowFiles AndAlso Not ddlFiles Is Nothing AndAlso ddlFiles.SelectedItem Is Nothing Then
                        If Not String.IsNullOrEmpty(ddlFiles.SelectedValue) Then
                            fid = Convert.ToInt32(ddlFiles.SelectedItem.Value)
                        End If
                    Else
                        If FileName <> String.Empty Then
                            fid = GetFileIDFromName(FileName)
                        End If
                    End If
                End If
                If fid = -1 Then
                    If FileName = String.Empty Then
                        Return String.Empty
                    Else
                        Return FilePath
                    End If
                Else
                    Return "FileID=" & fid.ToString
                End If
            End Get
            Set(ByVal Value As String)
                Dim rgx As RegularExpressions.Regex
                Dim m As RegularExpressions.Match
                If Not Value = String.Empty Then
                    rgx = New RegularExpressions.Regex("^\s*FileID=(\d+)\s*$", RegularExpressions.RegexOptions.IgnoreCase)
                    m = rgx.Match(Value)
                    If m.Success Then
                        Dim fid As Integer = Convert.ToInt32(m.Groups(1).Value)
                        Dim fc As New Services.FileSystem.FileController
                        Dim fi As Services.FileSystem.FileInfo = fc.GetFileById(fid, PortalId)
                        If Not fi Is Nothing Then
                            FileName = fi.FileName
                            FileID = fid
                            Folder = fi.Folder
                            FolderID = fi.FolderId
                        End If
                    Else
                        FilePath = Value
                    End If
                End If
            End Set
        End Property

        <Description("Provides access to the ImageEditor object for sub-properties not otherwise exposed.")> _
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Browsable(True)> _
        Public ReadOnly Property ImageEditor() As WESNet.AJAX.Controls.ImageEditor.ImageEditor
            Get
                EnsureChildControls()
                Return imgEditor
            End Get
        End Property

#End Region

#Region "Private Properties"

        Private ReadOnly Property EditorCreated() As Boolean
            Get
                Return (EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.Edit) AndAlso ChildControlsCreated
            End Get
        End Property

        Private ReadOnly Property IsAdminMenu() As Boolean
            Get
                Return PortalSettings.ActiveTab.ParentId = PortalSettings.AdminTabId
            End Get
        End Property

        Private ReadOnly Property IsHostMenu() As Boolean
            Get
                Return PortalSettings.ActiveTab.ParentId = PortalSettings.SuperTabId
            End Get
        End Property

        Private ReadOnly Property Portal() As Entities.Portals.PortalInfo
            Get
                If _Portal Is Nothing Then
                    Dim objPortals As New DotNetNuke.Entities.Portals.PortalController
                    If Not (Page.Request.QueryString("pid") Is Nothing) And _
                             (PortalSettings.ActiveTab.ParentId = PortalSettings.SuperTabId Or _
                              Entities.Users.UserController.GetCurrentUserInfo.IsSuperUser) Then
                        _Portal = objPortals.GetPortal(Int32.Parse(Page.Request.QueryString("pid")))
                    Else
                        _Portal = objPortals.GetPortal(PortalSettings.PortalId)
                    End If
                End If
                Return _Portal
            End Get
        End Property

        Private ReadOnly Property PortalId() As Integer
            Get
                If Portal Is Nothing Then
                    Return -1
                Else
                    Return Portal.PortalID
                End If
            End Get
        End Property

        Private ReadOnly Property ModulePath() As String
            Get
                Return Me.TemplateSourceDirectory & "/"
            End Get
        End Property

        'The following property is read-only and will contain a listing of all folders to which the
        'user has READ or WRITE access.  The type of each item in the list is DotNetNuke.Services.FileSystem.FolderInfo
        'Note that the Folders collection is NOT persisted across postbacks.

        Private ReadOnly Property Folders() As Generic.Dictionary(Of String, DotNetNuke.Services.FileSystem.FolderInfo)
            Get
                If _FolderList Is Nothing Then
                    _FolderList = New Generic.Dictionary(Of String, DotNetNuke.Services.FileSystem.FolderInfo)
                End If
                Return _FolderList
            End Get
        End Property

        'The following property is read-only and will contain a listing of all files to which the
        'user has READ or WRITE access in the current folder. The type of each item in the list is
        'DotNetNuke.Common.FileItem
        'Note that the Files collection is NOT persisted across postbacks.

        Private ReadOnly Property Files() As Generic.Dictionary(Of String, DotNetNuke.Services.FileSystem.FileInfo)
            Get
                If _FileList Is Nothing Then
                    _FileList = New Generic.Dictionary(Of String, DotNetNuke.Services.FileSystem.FileInfo)
                End If
                Return _FileList
            End Get
        End Property

#End Region

#Region "Events"
        Public Event FilepathChanged(ByVal e As System.EventArgs)
#End Region

#Region "Event Handlers"

        Private Sub ImageEditControl_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
            Page.RegisterRequiresControlState(Me)
        End Sub

        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            Try
                If (EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.Edit) Then
                    If Not pnlUpdate1 Is Nothing Then
                        If Not btnUpload Is Nothing Then Framework.AJAX.RegisterPostBackControl(btnUpload)
                        If Not btnEditMode Is Nothing Then Framework.AJAX.RegisterPostBackControl(btnEditMode)
                    End If
                    If Not Page.IsPostBack Then
                        InitializeEditorControls()
                    End If
                    Dim tmp As String = Localization.GetString("Same_As_Original", LocalResourceFile)
                    If Not String.IsNullOrEmpty(tmp) Then _SameAsOriginal = tmp
                End If
                ClearError()
            Catch exc As Exception    'Module failed to load
                ProcessModuleLoadException(Me, exc)
            End Try
        End Sub

        Private Sub InitializeEditorControls()

            If EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.Edit Then
                If ShowFolders Then BindFolders()
                If ShowFiles Then BindFiles()
                If AllowFileSaveAs Then SaveAsFilename = _SameAsOriginal
                btnCmd1.Text = Localization.GetString("Select_File_To_Open", LocalResourceFile)
                btnCmd2.Text = Localization.GetString("Select_File_To_Upload", LocalResourceFile)
                btnCancel.Text = Localization.GetString("Cancel_Selection", LocalResourceFile)
                ClearUpload()
            End If

        End Sub

        Private Sub ImageEditControl_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreRender
            If EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.Edit Then
                imgEditor.Visible = True
                If AllowModeSwitch AndAlso Not btnEditMode Is Nothing Then
                    btnEditMode.ImageUrl = "~/images/reset.gif"
                    btnEditMode.ToolTip = Localization.GetString("Return", LocalResourceFile)
                End If

                If AllowFileUpload Then
                    Dim sb As New StringBuilder
                    sb.AppendLine("function fileUpload_OnChange (sender, e, btnUploadID) {")
                    sb.AppendLine("   var btnUpload = $get(btnUploadID);")
                    sb.AppendLine("   if (btnUpload) {")
                    sb.AppendLine("       if (sender.value =='') {")
                    sb.AppendLine("           btnUpload.style.display='none';")
                    sb.AppendLine("       } else {")
                    sb.AppendLine("           btnUpload.style.display='';")
                    sb.AppendLine("       }")
                    sb.AppendLine("   }")
                    sb.AppendLine("}")
                    ScriptManager.RegisterClientScriptBlock(Me.Page, Me.GetType, "FileUploadChanged", sb.ToString, True)
                    If (Not fileUpload Is Nothing) AndAlso (Not btnUpload Is Nothing) Then
                        fileUpload.Attributes.Add("onchange", "fileUpload_OnChange(this, event,'" & btnUpload.ClientID & "');")
                    End If
                End If

                If AllowFileSave Then
                    Dim sb As New StringBuilder
                    sb.AppendLine("function imgEditor_IsDirtyChanged (sender) {")
                    sb.Append("      __doPostBack('")
                    sb.Append(imgEditor.UniqueID)
                    sb.AppendLine("',sender._imageGuid + '|DirtyChanged');")
                    sb.AppendLine("}")
                    ScriptManager.RegisterClientScriptBlock(Me.Page, Me.GetType, "DirtyChanged", sb.ToString, True)
                    If Not imgEditor Is Nothing AndAlso Not btnCmd1 Is Nothing Then
                        imgEditor.IsDirtyChanged = "imgEditor_IsDirtyChanged"
                    End If
                End If

                If Not lblError Is Nothing Then
                    lblError.Width = Unit.Pixel(PreviewSize.Width)
                End If

            Else
                imgEditor.Visible = False
                If AllowModeSwitch AndAlso Not btnEditMode Is Nothing Then
                    btnEditMode.ImageUrl = "~/images/eip_edit.gif"
                    btnEditMode.ToolTip = Localization.GetString("Edit", LocalResourceFile)
                    btnEditMode.Visible = IsEditable()
                End If

                If Not imgView Is Nothing Then
                    If String.IsNullOrEmpty(FileName) Then
                        'Show blank image
                        If ViewSize.IsEmpty Then
                            imgView.Visible = False
                            imgView.ImageUrl = String.Empty
                        Else
                            imgView.ImageUrl = String.Format(ApplicationPath & "/" & _
                                                  "DynamicImage.ashx?maxwidth={0}&maxheight={1}", _
                                                          ViewSize.Width, ViewSize.Height)
                        End If
                    Else
                        If IsSecureOrDatabaseFolder() Then
                            'Use image editor cache and DynamicImage HttpHandler
                            imgEditor.Image = GetImage(FileID, FilePath, ViewSize)
                            imgView.ImageUrl = imgEditor.GenerateDynamicImageUrl(ViewSize)
                        Else
                            If ViewSize.IsEmpty Then
                                'Show full size image as a standard image tag with filepath as src
                                imgView.ImageUrl = "~/" & Context.Server.UrlPathEncode(Path.Combine(Root, FilePath))
                                SetImageControlSizeByFileID(imgView, FileID)
                            ElseIf ViewSize.Equals(MaxThumbSize) AndAlso Not String.IsNullOrEmpty(ThumbFileName) Then
                                'Show thumbnail image
                                imgView.ImageUrl = "~/" & Context.Server.UrlPathEncode(Path.Combine(Root, ThumbPath)) & "?v=" & Now().Ticks.ToString
                                SetImageControlSizeByFileID(imgView, ThumbFileID)
                            Else
                                'Show custom size image
                                imgView.ImageUrl = String.Format(ApplicationPath & "/" & _
                                     "DynamicImage.ashx?path={0}&maxwidth={1}&maxheight={2}&v={3}", _
                                      Context.Server.UrlEncode(Path.Combine(Root, FilePath)), ViewSize.Width, ViewSize.Height, Now().Ticks)
                            End If
                        End If

                    End If
                End If
            End If
        End Sub

        Protected Sub ImageEditor_SelectFile(ByVal sender As Object, ByVal e As System.EventArgs) 'Handles imgEditor.SelectFile
            SelectFile()
            pnlUpdate2.Update()
        End Sub

        Protected Sub ImageEditor_SelectUpload(ByVal sender As Object, ByVal e As System.EventArgs) 'Handles imgEditor.SelectUpload
            SelectUpload()
            pnlUpdate2.Update()
        End Sub

        Protected Sub ImageEditor_DirtyChanged(ByVal sender As Object, ByVal e As System.EventArgs) 'Handles imgEditor.DirtyChanged
            If CType(sender, WESNet.AJAX.Controls.ImageEditor.ImageEditor).IsDirty Then
                btnCmd1.Text = Localization.GetString("Save_Modified_File", LocalResourceFile)
                btnCmd1.CommandName = "savechanges"
                SetVisibility("btnCmd1", CanWrite(Folder))
                SetVisibility("btnCmd2", False)
                SetVisibility("btnUpload", False)
                btnCancel.Text = Localization.GetString("Cancel_Selection", LocalResourceFile)
                btnCancel.CommandName = "cancel"
                SetVisibility("btnCancel", True)
                If ShowFolders AndAlso ddlFolders.Items.Count > 1 Then SetVisibility("divFolders", True)
                If AllowFileSaveAs Then
                    SaveAsFilename = _SameAsOriginal
                    SetVisibility("divSaveAs", True)
                End If
                pnlUpdate2.Update()
            End If
        End Sub

        Protected Sub ImageEditor_SaveImage(ByVal sender As Object, ByVal e As System.EventArgs) 'Handles imgEditor.SaveImage
            Save()
            pnlUpdate2.Update()
        End Sub

        Private Sub btnCmd_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) 'Handles btnCmd1.Command, btnCmd2.Command

            Select Case e.CommandName
                Case "selectfile"
                    SelectFile()
                Case "selectupload"
                    SelectUpload()
                Case "saveupload", "savechanges"
                    Save()
            End Select
        End Sub

        Private Sub SelectFile()
            If ShowFolders AndAlso ddlFolders.Items.Count > 1 Then SetVisibility("divFolders", True)
            If ShowFiles Then SetVisibility("divFiles", True)
            If AllowFileUpload Then SetVisibility("divUpload", False)
            If AllowFileSaveAs Then SetVisibility("divSaveAs", False)
            SetVisibility("btnCmd1", False)
            SetVisibility("btnCmd2", False)
            SetVisibility("btnUpload", False)
            btnCancel.Text = Localization.GetString("Cancel_Selection", LocalResourceFile)
            btnCancel.CommandName = "cancel"
            SetVisibility("btnCancel", True)
        End Sub

        Private Sub SelectUpload()
            If ShowFolders Then SetVisibility("divFolders", False)
            If ShowFiles Then SetVisibility("divFiles", False)
            SetVisibility("divUpload", True)
            If AllowFileSaveAs Then SetVisibility("divSaveAs", False)
            SetVisibility("btnCmd1", False)
            SetVisibility("btnCmd2", False)
            SetVisibility("btnCancel", True)
            btnCancel.Text = Localization.GetString("Cancel_Selection", LocalResourceFile)
            btnCancel.CommandName = "cancel"
        End Sub

        Private Sub Save()
            Dim Result As Integer
            Dim DuplicateAction As Utilities.DuplicateActions

            If Not CanWrite(Folder) Then
                ShowError(Localization.GetString("No_Write_Permission", LocalResourceFile))
                Exit Sub
            End If

            Select Case imgEditor.ImageSource
                Case "U"
                    DuplicateAction = Utilities.DuplicateActions.MakeUnique
                    If imgEditor.Image Is Nothing Then
                        If HasUpload Then
                            imgEditor.Image = New System.Drawing.Bitmap(PostedFile.InputStream)
                            imgEditor.ImageSource = "U"
                        Else
                            ShowError(Localization.GetString("Uploaded_file_data_expired", LocalResourceFile))
                            ClearUpload()
                            Exit Sub
                        End If
                    End If
                Case "F"
                    If AllowFileSaveAs And SaveAsFilename <> _SameAsOriginal Then
                        DuplicateAction = Utilities.DuplicateActions.MakeUnique
                    Else
                        DuplicateAction = Utilities.DuplicateActions.Replace
                    End If
                    If imgEditor.Image Is Nothing Then
                        ShowError(Localization.GetString("Modified_image_data_expired", LocalResourceFile))
                        imgEditor.Image = GetImage()
                    End If
                Case "L"
                    'TO DO: Refresh the image from hyperlink URL
            End Select

            If imgEditor.Image Is Nothing Then
                ShowError(Localization.GetString("No_Image_Data", LocalResourceFile))
                Exit Sub
            End If

            If SaveAsFilename <> _SameAsOriginal Then
                Dim tmpFileName As String = Utilities.AddDefaultExtension(SaveAsFilename, ".jpg")
                Dim ext As String = Replace(Path.GetExtension(tmpFileName), ".", "")
                If FileFilter <> "" And InStr("," & FileFilter.ToLower, "," & ext.ToLower) = 0 Then
                    ShowError(Localization.GetString("Invalid_File_Extension", LocalResourceFile) & ext)
                    Exit Sub
                Else
                    FileName = tmpFileName
                End If
                SaveAsFilename = _SameAsOriginal
            End If

            Result = Utilities.SaveImage(imgEditor.Image, ParentPath, FilePath, "", DuplicateAction, Quality, UseOctreeQuantizer, Portal)
            If Result < 0 Then
                ShowError(Localization.GetString("Cannot_Save_Image", LocalResourceFile) & " " & ResolvePath(FilePath) & " - " & GetSaveImageErrorMessage(Result))
                Exit Sub
            Else
                FileID = Result
            End If

            If AutoThumbnail Then
                ThumbFileName = Utilities.InsertFileSuffix(FileName, ThumbSuffix)
                _Thumb = WESNet.Utilities.ImageUtilities.CreateResizedImage(imgEditor.Image, MaxThumbSize.Width, MaxThumbSize.Height, LockAspect, 1.0!)
                Result = Utilities.SaveImage(_Thumb, ParentPath, ThumbPath, ThumbSuffix, DuplicateAction, Quality, UseOctreeQuantizer, Portal)
                If Result < 0 Then
                    ShowError(Localization.GetString("Cannot_Save_Thumb", LocalResourceFile) & " " & ResolvePath(ThumbPath) & " - " & GetSaveImageErrorMessage(Result))
                    If FileID > 0 And DuplicateAction = Utilities.DuplicateActions.MakeUnique Then
                        Utilities.DeleteFile(FileID, ParentPath, PortalId, True)
                        FileID = -1
                    End If
                    Exit Sub
                Else
                    ThumbFileID = Result
                End If
            End If

            IsDirty = False
            imgEditor.Filename = FileName
            imgEditor.ImageSource = "F"
            OnFilepathChanged(New System.EventArgs)
            If Not pnlUpdate1 Is Nothing Then pnlUpdate1.Update()
            Initialize(False)
            BindFiles()
        End Sub

        Private Sub btnUpload_Command(ByVal Sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) 'Handles btnUpload.Command
            If fileUpload.FileName = String.Empty Then
                ShowError(Localization.GetString("No_fileUpload_Selected", LocalResourceFile))
                SetVisibility("btnUpload", False)
            Else
                Dim ext As String = Replace(Path.GetExtension(fileUpload.FileName), ".", "")
                If FileFilter <> "" And InStr("," & FileFilter.ToLower, "," & ext.ToLower) = 0 Then
                    ShowError(Localization.GetString("Invalid_File_Extension", LocalResourceFile) & ext)
                Else
                    PostedFile = fileUpload.PostedFile
                    If HasUpload Then
                        Dim img As System.Drawing.Bitmap
                        If AutoResize Then
                            img = WESNet.Utilities.ImageUtilities.CreateResizedImage(New System.Drawing.Bitmap(PostedFile.InputStream), _
                                                                                     MaxImageSize.Width, MaxImageSize.Height, LockAspect, MaxMagnification)
                        Else
                            img = New System.Drawing.Bitmap(PostedFile.InputStream)
                        End If
                        If img Is Nothing Then
                            ShowError(Localization.GetString("File_Upload_Failed", LocalResourceFile))
                            img = WESNet.Utilities.ImageUtilities.CreateBlankImage(MaxImageSize, Drawing.Color.Black)
                            SetVisibility("btnUpload", False)
                        Else
                            FileName = UploadFilename
                            With imgEditor
                                .ImageSource = "U"
                                .IsDirty = True
                                .Filename = FileName
                                .InvalidateImageCache()
                                .Image = img
                            End With

                            If Not pnlUpdate1 Is Nothing Then pnlUpdate1.Update()

                            If ShowFolders AndAlso ddlFolders.Items.Count > 1 Then SetVisibility("divFolders", True)
                            If ShowFiles Then SetVisibility("divFiles", False)
                            SetVisibility("divUpload", False)
                            If AllowFileSaveAs Then
                                SetVisibility("divSaveAs", True)
                                SaveAsFilename = _SameAsOriginal
                            End If
                            btnCmd1.Text = Localization.GetString("Save_Uploaded_File", LocalResourceFile)
                            btnCmd1.CommandName = "saveupload"
                            SetVisibility("btnCmd1", CanWrite(Folder))
                            SetVisibility("btnCmd2", False)
                            SetVisibility("btnUpload", False)
                            btnCancel.Text = Localization.GetString("Discard_Uploaded_File", LocalResourceFile)
                            btnCancel.CommandName = "discard"
                            SetVisibility("btnCancel", True)
                        End If
                    Else
                        ShowError(Localization.GetString("File_Upload_Failed", LocalResourceFile))
                        SetVisibility("btnUpload", fileUpload.FileName <> String.Empty)
                    End If
                End If
            End If
        End Sub

        Private Sub btnCancel_Command(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.CommandEventArgs) 'Handles btnCancel.Command
            Select Case e.CommandName
                Case "cancel"
                    Initialize(False)
                Case "discard"
                    ClearUpload()
            End Select
        End Sub

        Private Sub ddlFolders_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) 'Handles ddlFolders.SelectedIndexChanged
            GetSelectedFolder()
            imgEditor.Parentpath = Me.ResolvePath(Folder)
            BindFiles()
            ClearError()
        End Sub

        Private Sub ddlFiles_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) 'Handles ddlFiles.SelectedIndexChanged
            GetSelectedFile()
            If FileName = String.Empty Then
                ThumbFileID = -1
                ThumbFileName = String.Empty
            Else
                With imgEditor
                    .ImageSource = "F"
                    .IsDirty = False
                    .Filename = FileName
                    .InvalidateImageCache()
                    .Image = GetImage()
                End With

                OnFilepathChanged(New System.EventArgs)

                If Not pnlUpdate1 Is Nothing Then pnlUpdate1.Update()

                If ShowFolders Then SetVisibility("divFolders", False)
                If ShowFiles Then SetVisibility("divFiles", False)
                If AllowFileSaveAs Then SaveAsFilename = _SameAsOriginal
            End If
            ClearError()
        End Sub

        Private Sub btnEditMode_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) 'Handles btnEditMode.Click
            If EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.View Then
                If IsEditable() Then
                    EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.Edit
                    InitializeEditorControls()
                End If
            Else
                If IsDirty Then Save()
                EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.View
            End If
        End Sub
#End Region

#Region "Overridden Methods"

        Protected Overrides Function SaveControlState() As Object
            Return _EditMode
        End Function

        Protected Overrides Sub LoadControlState(ByVal savedState As Object)
            _EditMode = CType(savedState, DotNetNuke.UI.WebControls.PropertyEditorMode)
        End Sub

        Protected Overrides ReadOnly Property TagKey() As System.Web.UI.HtmlTextWriterTag
            Get
                Return System.Web.UI.HtmlTextWriterTag.Table
            End Get
        End Property

        Protected Overrides Sub CreateChildControls()
            Controls.Clear()
            Dim _parentControl As System.Web.UI.Control
            Dim trContainer As New System.Web.UI.WebControls.TableRow
            Dim tdContainer As New System.Web.UI.WebControls.TableCell

            If Framework.AJAX.IsInstalled Then
                Framework.AJAX.RegisterScriptManager()
                pnlUpdate1 = New System.Web.UI.UpdatePanel
                With pnlUpdate1
                    .ID = "pnlUpdate1"
                    .UpdateMode = UpdatePanelUpdateMode.Conditional
                    .ChildrenAsTriggers = False
                End With
                tdContainer.Controls.Add(pnlUpdate1)
                _parentControl = pnlUpdate1.ContentTemplateContainer
            Else
                pnlUpdate1 = Nothing
                _parentControl = tdContainer
            End If
            trContainer.Cells.Add(tdContainer)
            Controls.Add(trContainer)

            If AllowModeSwitch Then
                btnEditMode = New System.Web.UI.WebControls.ImageButton
                With btnEditMode
                    .ID = "btnEditMode"
                    .Style.Add("float", "left")
                End With
                AddHandler btnEditMode.Click, AddressOf btnEditMode_Click
                tdContainer.Controls.AddAt(0, btnEditMode)
            End If

            'imgEditor = New WESNet.AJAX.Controls.ImageEditor.ImageEditor()
            With imgEditor
                .ID = "imgEditor"
                .Style.Add("float", "right")
                .Visible = False
            End With
            _parentControl.Controls.Add(imgEditor)

            If EditMode = DotNetNuke.UI.WebControls.PropertyEditorMode.Edit Then
                If Framework.AJAX.IsInstalled Then
                    pnlUpdate2 = New System.Web.UI.UpdatePanel
                    With pnlUpdate2
                        .ID = "pnlUpdate2"
                        .UpdateMode = UpdatePanelUpdateMode.Conditional
                    End With
                    _parentControl.Controls.Add(pnlUpdate2)
                    _parentControl = pnlUpdate2.ContentTemplateContainer
                End If

                If AllowFileOpen Then AddHandler imgEditor.SelectFile, AddressOf ImageEditor_SelectFile
                If AllowFileUpload Then AddHandler imgEditor.SelectUpload, AddressOf ImageEditor_SelectUpload
                If AllowFileSave Then
                    AddHandler imgEditor.DirtyChanged, AddressOf ImageEditor_DirtyChanged
                    AddHandler imgEditor.SaveImage, AddressOf ImageEditor_SaveImage
                End If

                If ShowFolders Then
                    Dim divFolders As New HtmlControls.HtmlGenericControl("div")
                    With divFolders
                        .ID = "divFolders"
                        .Style.Add("width", "100%")
                        .Style.Add("float", "right")
                        .Style.Add("clear", "both")
                        .Style.Add("display", "none")
                    End With
                    lblFolder = BuildLabel("Folder", Unit.Percentage(20.0#), DotNetNuke.UI.WebControls.LabelMode.Right)
                    imgStorageLocationIcon = New System.Web.UI.WebControls.Image
                    With imgStorageLocationIcon
                        .ID = "imgStorageLocationIcon"
                        .Visible = False
                    End With
                    lblFolder.Controls.AddAt(0, imgStorageLocationIcon)
                    divFolders.Controls.Add(lblFolder)
                    ddlFolders = New System.Web.UI.WebControls.DropDownList
                    With ddlFolders
                        .ID = "ddlFolders"
                        .AutoPostBack = True
                        .Width = Unit.Percentage(79.0#)
                        .CssClass = "NormalTextBox"
                    End With
                    divFolders.Controls.Add(ddlFolders)
                    AddHandler ddlFolders.SelectedIndexChanged, AddressOf ddlFolders_SelectedIndexChanged
                    _parentControl.Controls.Add(divFolders)
                    lblFolder.Attributes.Add("for", ddlFolders.ClientID)
                End If

                If ShowFiles Then
                    Dim divFiles As New HtmlControls.HtmlGenericControl("div")
                    With divFiles
                        .ID = "divFiles"
                        .Style.Add("width", "100%")
                        .Style.Add("float", "right")
                        .Style.Add("clear", "both")
                        .Style.Add("display", "none")
                    End With
                    lblFile = BuildLabel("File", Unit.Percentage(20.0#), DotNetNuke.UI.WebControls.LabelMode.Right)
                    divFiles.Controls.Add(lblFile)
                    ddlFiles = New System.Web.UI.WebControls.DropDownList
                    With ddlFiles
                        .ID = "ddlFiles"
                        .AutoPostBack = True
                        .Width = Unit.Percentage(79.0#)
                        .CssClass = "NormalTextBox"
                    End With
                    divFiles.Controls.Add(ddlFiles)
                    AddHandler ddlFiles.SelectedIndexChanged, AddressOf ddlFiles_SelectedIndexChanged
                    _parentControl.Controls.Add(divFiles)
                    lblFile.Attributes.Add("for", ddlFiles.ClientID)
                End If

                'If AllowFileUpload Then
                Dim divUpload As New HtmlControls.HtmlGenericControl("div")
                With divUpload
                    .ID = "divUpload"
                    .Style.Add("width", "100%")
                    .Style.Add("float", "right")
                    .Style.Add("clear", "both")
                    .Style.Add("display", "none")
                End With
                lblUpload = BuildLabel("Upload_From", Unit.Percentage(20.0#), DotNetNuke.UI.WebControls.LabelMode.Right)
                divUpload.Controls.Add(lblUpload)
                fileUpload = New System.Web.UI.WebControls.FileUpload()
                With fileUpload
                    .ID = "fileUpload"
                    .CssClass = "NormalTextBox"
                    .Width = Unit.Percentage(79.0#)
                End With
                divUpload.Controls.Add(fileUpload)
                _parentControl.Controls.Add(divUpload)
                lblUpload.Attributes.Add("for", fileUpload.ClientID)
                AddHandler imgEditor.SelectUpload, AddressOf ImageEditor_SelectUpload
                'End If

                'If AllowFileSaveAs Then
                Dim divSaveAs As New HtmlControls.HtmlGenericControl("div")
                With divSaveAs
                    .ID = "divSaveAs"
                    .Style.Add("width", "100%")
                    .Style.Add("float", "right")
                    .Style.Add("clear", "both")
                    .Style.Add("display", "none")
                End With
                lblSaveAs = BuildLabel("Save_As", Unit.Percentage(20.0#), DotNetNuke.UI.WebControls.LabelMode.Right)
                divSaveAs.Controls.Add(lblSaveAs)
                tbSaveAs = New System.Web.UI.WebControls.TextBox
                With tbSaveAs
                    .ID = "tbSaveAs"
                    .CssClass = "NormalTextBox"
                    .Width = Unit.Percentage(79.0#)
                End With
                divSaveAs.Controls.Add(tbSaveAs)
                _parentControl.Controls.Add(divSaveAs)
                lblSaveAs.Attributes.Add("for", tbSaveAs.ClientID)
                'End If

                Dim divButtons As New HtmlControls.HtmlGenericControl("div")
                With divButtons
                    .ID = "divButtons"
                    .Style.Add("width", "100%")
                    .Style.Add("float", "right")
                    .Style.Add("clear", "both")
                    .Style.Add("text-align", "center")
                End With
                btnCmd1 = New System.Web.UI.WebControls.LinkButton
                With btnCmd1
                    .ID = "btnCmd1"
                    .CommandName = "selectfile"
                    .CssClass = "CommandButton"
                End With
                divButtons.Controls.Add(btnCmd1)
                AddHandler btnCmd1.Command, AddressOf btnCmd_Command
                divButtons.Controls.Add(New LiteralControl("&nbsp;"))

                btnCmd2 = New System.Web.UI.WebControls.LinkButton
                With btnCmd2
                    .ID = "btnCmd2"
                    .CommandName = "selectupload"
                    .CssClass = "CommandButton"
                End With
                divButtons.Controls.Add(btnCmd2)
                AddHandler btnCmd2.Command, AddressOf btnCmd_Command
                divButtons.Controls.Add(New LiteralControl("&nbsp;"))

                btnUpload = New System.Web.UI.WebControls.LinkButton
                With btnUpload
                    .ID = "btnUpload"
                    .CommandName = "upload"
                    .CssClass = "CommandButton"
                    .Attributes.Add("resourcekey", "Upload_Selected_File.Text")
                End With
                divButtons.Controls.Add(btnUpload)
                AddHandler btnUpload.Command, AddressOf btnUpload_Command

                divButtons.Controls.Add(New LiteralControl("&nbsp;"))
                btnCancel = New System.Web.UI.WebControls.LinkButton
                With btnCancel
                    .ID = "btnCancel"
                    .CommandName = "cancel"
                    .CssClass = "CommandButton"
                End With
                divButtons.Controls.Add(btnCancel)
                AddHandler btnCancel.Command, AddressOf btnCancel_Command
                _parentControl.Controls.Add(divButtons)

                Dim divMessage As New HtmlControls.HtmlGenericControl("div")
                With divMessage
                    .ID = "divMessage"
                    .Style.Add("width", "100%")
                    .Style.Add("float", "right")
                    .Style.Add("clear", "both")
                    .Style.Add("margin-top", "10px")
                    .Style.Add("text-align", "right")
                End With

                lblError = New System.Web.UI.WebControls.Label
                With lblError
                    .ID = "lblError"
                    .CssClass = "NormalRed"
                End With
                divMessage.Controls.Add(lblError)
                _parentControl.Controls.Add(divMessage)
            Else
                imgView = New System.Web.UI.WebControls.Image
                imgView.ID = "imgView"
                imgView.Style.Add("text-align", "center")
                _parentControl.Controls.Add(imgView)
            End If
            ClearChildViewState()
            ChildControlsCreated = True
        End Sub

        Protected Overridable Sub OnFilepathChanged(ByVal e As System.EventArgs)
            RaiseEvent FilepathChanged(e)
        End Sub

        'Protected Overridable Sub OnUrlChanged()
        '    Dim _Url As String = Convert.ToString(ViewState("Url"))
        '    If _Url <> "" Then
        '        Dim objFiles As New FileController
        '        If _Url.ToLower.StartsWith("fileid=") Then
        '            Dim objFile As DotNetNuke.Services.FileSystem.FileInfo = objFiles.GetFileById(Integer.Parse(_Url.Substring(7)), PortalId)
        '            If Not objFile Is Nothing Then
        '                _Url = objFile.Folder & objFile.FileName
        '            End If
        '        End If
        '        ViewState("Url") = _Url
        '    End If
        'End Sub

#End Region

#Region "Private Methods"

        Private Function BuildLabel(ByVal ID As String, ByVal Width As System.Web.UI.WebControls.Unit, ByVal Alignment As DotNetNuke.UI.WebControls.LabelMode) As System.Web.UI.HtmlControls.HtmlGenericControl
            Dim lblContainer As New System.Web.UI.HtmlControls.HtmlGenericControl("label")
            Dim lblText = New System.Web.UI.WebControls.Label
            With lblText
                .ID = "lbl" + ID
                .EnableViewState = False
                .CssClass = "NormalBold"
                .Attributes.Add("resourcekey", ID + ".Text")
            End With
            If Not Width.Equals(Unit.Empty) AndAlso Alignment <> DotNetNuke.UI.WebControls.LabelMode.None Then
                With lblContainer
                    .Style.Add("width", Width.ToString)
                    Select Case Alignment
                        Case DotNetNuke.UI.WebControls.LabelMode.Left
                            .Style.Add("text-align", "left")
                        Case DotNetNuke.UI.WebControls.LabelMode.Right
                            .Style.Add("text-align", "right")
                            .Style.Add("margin-right", "4px")
                    End Select
                End With
            End If
            lblContainer.Controls.Add(lblText)
            Return lblContainer
        End Function

        Private Sub ClearUpload()
            Initialize(True)
        End Sub

        Private Sub Initialize(ByVal Clear As Boolean)
            If Clear Then
                With ImageEditor
                    .InvalidateImageCache()
                    .ImageSource = "F"
                    .IsDirty = False
                    If FileName = String.Empty Then
                        .Filename = FileName
                        .Image = WESNet.Utilities.ImageUtilities.CreateBlankImage(MaxImageSize, System.Drawing.Color.Black)
                    Else
                        .Parentpath = ResolvePath(Folder)
                        .Filename = FileName
                        .Image = GetImage()
                    End If
                End With
                PostedFile = Nothing
                If Not pnlUpdate1 Is Nothing Then pnlUpdate1.Update()
            End If

            SetVisibility("divFolders", False)
            SetVisibility("divFiles", False)
            SetVisibility("divUpload", False)
            SetVisibility("divSaveAs", False)

            If AllowFileOpen And CanRead(Folder) Then
                SetVisibility("btnCmd1", True)
                btnCmd1.Text = Localization.GetString("Select_File_To_Open", LocalResourceFile)
                btnCmd1.CommandName = "selectfile"
            Else
                SetVisibility("btnCmd1", False)
                btnCmd1.Text = ""
                btnCmd1.CommandName = ""
            End If

            If AllowFileUpload Then
                SetVisibility("btnCmd2", True)
                btnCmd2.Text = Localization.GetString("Select_File_To_Upload", LocalResourceFile)
                btnCmd2.CommandName = "selectupload"
            Else
                SetVisibility("btnCmd2", False)
                btnCmd2.Text = ""
                btnCmd2.CommandName = ""
            End If

            SetVisibility("btnUpload", False)
            SetVisibility("btnCancel", False)
        End Sub

        Private Sub ShowError(ByVal Text As String)
            If Not lblError Is Nothing Then lblError.Text = Text
        End Sub

        Private Sub ClearError()
            ShowError(String.Empty)
        End Sub

        Private Sub SetVisibility(ByVal ID As String, ByVal Visible As Boolean)
            Dim Control As System.Web.UI.Control = Common.FindControlRecursiveDown(Me, ID)
            If Not Control Is Nothing Then
                If TypeOf Control Is System.Web.UI.WebControls.WebControl Then
                    Dim WebControl As System.Web.UI.WebControls.WebControl = CType(Control, System.Web.UI.WebControls.WebControl)
                    If Visible Then
                        WebControl.Style.Remove("display")
                    Else
                        WebControl.Style.Add("display", "none")
                    End If
                ElseIf TypeOf Control Is System.Web.UI.HtmlControls.HtmlGenericControl Then
                    Dim HtmlControl As System.Web.UI.HtmlControls.HtmlGenericControl = CType(Control, System.Web.UI.HtmlControls.HtmlGenericControl)
                    If Visible Then
                        HtmlControl.Style.Remove("display")
                    Else
                        HtmlControl.Style.Add("display", "none")
                    End If
                End If
            End If
        End Sub

        Private Sub LoadFiles()
            Dim fileList As ArrayList
            If FolderID = -1 Then
                SetFolderID()
            End If
            If IsHostMenu Then
                fileList = FileSystemUtils.GetFilesByFolder(-1, FolderID)
            Else
                fileList = FileSystemUtils.GetFilesByFolder(PortalId, FolderID)
            End If
            Files.Clear()
            For Each file As Services.FileSystem.FileInfo In fileList
                If MatchesFileFilter(file.Extension) Then
                    If ShowThumbs OrElse Not Path.GetFileNameWithoutExtension(file.FileName).EndsWith(ThumbSuffix) Then
                        Files.Add(file.FileName, file)
                    End If
                End If
            Next
        End Sub

        Private Function MatchesFileFilter(ByVal ContentType As String) As Boolean
            Dim IsMatch As Boolean
            If String.IsNullOrEmpty(ContentType) OrElse String.IsNullOrEmpty(FileFilter) Then
                IsMatch = True
            Else
                ContentType = ContentType.ToLower
                For Each s As String In FileFilter.Split(","c)
                    If ContentType = s Then
                        IsMatch = True
                        Exit For
                    End If
                Next
            End If
            Return IsMatch
        End Function

        Private Function GetReadRoles(ByVal Folder As String) As String
            Return FileSystemUtils.GetRoles(Folder, PortalId, "READ")
        End Function

        Private Function GetWriteRoles(ByVal Folder As String) As String
            Return FileSystemUtils.GetRoles(Folder, PortalId, "WRITE")
        End Function

        Private Sub LoadFolders(ByVal InitialPath As String)
            Dim NoInitialPath As Boolean = String.IsNullOrEmpty(InitialPath)

            Dim pid As Integer = -1
            If Not IsHostMenu Then
                pid = PortalId
            End If

            Dim _folders As ArrayList = FileSystemUtils.GetFoldersByUser(pid, ShowSecure, ShowDatabase, "READ, WRITE")
            Folders.Clear()

            For Each _folder As Services.FileSystem.FolderInfo In _folders
                If NoInitialPath OrElse _folder.FolderPath.StartsWith(InitialPath, StringComparison.CurrentCultureIgnoreCase) Then
                    Folders.Add(_folder.FolderPath, _folder)
                End If
            Next
        End Sub

        Private Function AddFolder(ByVal NewFolderName As String) As Boolean
            If NewFolderName Is Nothing OrElse NewFolderName.Length = 0 Then
                Return False
            End If

            Try
                FileSystemUtils.AddFolder(PortalSettings, Folder.TrimEnd("/"c), NewFolderName)
                Folder = FileSystemUtils.AddTrailingSlash(Folder & NewFolderName)
                If ShowFolders Then BindFolders()
                Return True
            Catch ex As Exception
                ShowError(Localization.GetString("Cannot_Create_Folder", LocalResourceFile))
                Return False
            End Try
        End Function

        Private Function CanWrite(ByVal Folder As String) As Boolean
            Dim strWriteRoles As String = GetWriteRoles(Folder.Replace("\", "/"))
            Return DotNetNuke.Security.PortalSecurity.IsInRoles(strWriteRoles)
        End Function

        Private Function CanRead(ByVal Folder As String) As Boolean
            Dim strReadRoles As String = GetReadRoles(Folder.Replace("\", "/"))
            Return DotNetNuke.Security.PortalSecurity.IsInRoles(strReadRoles)
        End Function

        Private Function IsSecureOrDatabaseFolder() As Boolean
            Dim objFolder As New FolderController
            Dim objFolderInfo As FolderInfo
            objFolderInfo = objFolder.GetFolder(PortalId, Folder, False)

            If objFolderInfo Is Nothing Then
                Return False
            Else
                Return objFolderInfo.StorageLocation <> FolderController.StorageLocationTypes.InsecureFileSystem
            End If
        End Function

        Private Sub SetStorageLocationIcon()
            Dim objFolder As New FolderController
            Dim objFolderInfo As FolderInfo

            objFolderInfo = objFolder.GetFolder(PortalId, Folder, False)

            If Not objFolderInfo Is Nothing Then
                Select Case objFolderInfo.StorageLocation
                    Case FolderController.StorageLocationTypes.InsecureFileSystem
                        imgStorageLocationIcon.Visible = False
                    Case FolderController.StorageLocationTypes.SecureFileSystem
                        imgStorageLocationIcon.ImageUrl = ResolveUrl("~/images/icon_securityroles_16px.gif")
                        imgStorageLocationIcon.Visible = True
                    Case FolderController.StorageLocationTypes.DatabaseSecure
                        imgStorageLocationIcon.ImageUrl = ResolveUrl("~/images/icon_sql_16px.gif")
                        imgStorageLocationIcon.Visible = True
                End Select
            End If
        End Sub

        Private Sub SetSelectedFolder()
            Dim li As ListItem
            Dim FolderPath As String
            If ShowFolders Then
                If Folder = String.Empty Then
                    FolderPath = Localization.GetString("Root", LocalResourceFile)
                Else
                    FolderPath = Folder
                End If
                li = ddlFolders.Items.FindByText(FolderPath)
                If Not li Is Nothing Then
                    ddlFolders.SelectedIndex = ddlFolders.Items.IndexOf(li)
                    If li.Value <> "-1" Then
                        FolderID = Convert.ToInt32(li.Value)
                    End If
                    SetStorageLocationIcon()
                End If
            End If
        End Sub

        Private Sub GetSelectedFolder()
            Dim li As ListItem = ddlFolders.SelectedItem
            If Not li Is Nothing Then
                If ddlFolders.SelectedItem.Text = Localization.GetString("Root", LocalResourceFile) Then
                    Folder = String.Empty
                Else
                    Folder = li.Text
                    SetStorageLocationIcon()
                End If
                FolderID = Convert.ToInt32(li.Value)
                If btnCmd1.CommandName.StartsWith("save") Then
                    SetVisibility("btnCmd1", CanWrite(Folder))
                End If
            End If
        End Sub

        Private Sub SetSelectedFile()
            Dim li As ListItem = Nothing
            If ShowFiles Then
                If FileName <> String.Empty Then
                    li = ddlFiles.Items.FindByText(FileName)
                End If
                If li Is Nothing Then
                    ddlFiles.SelectedIndex = 0
                Else
                    ddlFiles.SelectedIndex = ddlFiles.Items.IndexOf(li)
                    FileID = Convert.ToInt32(li.Value)
                    SetThumbFileID()
                End If
            End If
        End Sub

        Private Function GetFolderIDFromName(ByVal folder As String) As Integer
            Dim folderID As Integer = -1
            If Not String.IsNullOrEmpty(folder) Then
                Dim fldc As New Services.FileSystem.FolderController
                Dim fldi As Services.FileSystem.FolderInfo = fldc.GetFolder(PortalId, folder, False)
                If Not fldi Is Nothing Then
                    folderID = fldi.FolderID
                End If
            End If
            Return folderID
        End Function

        Private Sub SetFolderID()
            FolderID = GetFolderIDFromName(Folder)
        End Sub

        Private Function GetFileIDFromName(ByVal fileName As String) As Integer
            Dim fileID As Integer = -1
            If Not String.IsNullOrEmpty(fileName.Replace(ThumbSuffix, "")) Then
                Dim fc As New Services.FileSystem.FileController
                Dim fi As Services.FileSystem.FileInfo
                Dim fldId As Integer
                If FolderID = -1 Then
                    fldId = GetFolderIDFromName(Folder)
                Else
                    fldId = FolderID
                End If
                fi = fc.GetFile(fileName, PortalId, fldId)
                If Not fi Is Nothing Then
                    fileID = fi.FileId
                End If
            End If
            Return fileID
        End Function

        Private Sub SetThumbFileID()
            ThumbFileID = GetFileIDFromName(ThumbFileName)
        End Sub

        Private Sub SetFileID()
            FileID = GetFileIDFromName(FileName)
        End Sub

        Private Sub GetSelectedFile()
            Dim li As ListItem
            If ddlFiles.SelectedIndex <> 0 Then
                li = ddlFiles.SelectedItem
                FileName = li.Text
                FileID = Convert.ToInt32(li.Value)
                SetThumbFileID()
            Else
                FileName = String.Empty
                FileID = -1
                ThumbFileID = -1
            End If
        End Sub

        Private Sub BindFolders()
            LoadFolders(Nothing)
            If ShowFolders Then
                ddlFolders.DataTextField = "FolderPath"
                ddlFolders.DataValueField = "FolderID"
                ddlFolders.DataSource = Folders.Values
                ddlFolders.DataBind()
                If ddlFolders.Items.Count > 0 AndAlso ddlFolders.Items(0).Text = String.Empty Then
                    ddlFolders.Items(0).Text = Localization.GetString("Root", LocalResourceFile)
                End If
                SetSelectedFolder()
            End If
        End Sub

        Private Sub BindFiles()
            LoadFiles()
            If ShowFiles Then
                ddlFiles.DataTextField = "FileName"
                ddlFiles.DataValueField = "FileID"
                ddlFiles.DataSource = Files.Values
                ddlFiles.DataBind()
                ddlFiles.Items.Insert(0, New ListItem("<" & Localization.GetString("None_Specified") & ">", "-1"))
                SetSelectedFile()
            End If
        End Sub

        'Returns a localized message from SaveImage error number
        Private Function GetSaveImageErrorMessage(ByVal ErrNumber As Integer) As String
            Dim MsgKey As String
            Select Case Math.Abs(ErrNumber)
                Case 1
                    MsgKey = "Image_Object_Null"       'Image object is null
                Case 2
                    MsgKey = "Filename_Null"           'Filename is null
                Case 3
                    MsgKey = "Save_To_Stream_Error"    'Error in saving image data to memory stream
                Case 4
                    MsgKey = "Image_Data_Null"         'Image data is null
                Case 5
                    MsgKey = "Insufficient_Space"      'Insufficient portal filespace in which to save image data
                Case 6
                    MsgKey = "Folder_Not_Found"        'Folder not found in DNN Folders database
                Case 7
                    MsgKey = "Duplicate_File_Abort"    'Existing of file of same name - save aborted
                Case 8
                    MsgKey = "Duplicate_File_Error"    'Existing file of same name cannot be replaced or made unique.
                Case 9
                    MsgKey = "Add_DNN_File_Error"      'File could not be added to DNN Files datatable
                Case 10
                    MsgKey = "Write_Stream_Error"      'Could not write memory stream to storage location
                Case Else
                    MsgKey = "Unknown_SaveImage_Error" 'Unknown image save error
            End Select
            Return Localization.GetString(MsgKey, LocalResourceFile)
        End Function

        Private Function ResolvePath(ByVal RelativePath As String) As String
            Return (ParentPath & RelativePath).Replace("\", "/")
        End Function

        Private Overloads Function GetImage() As System.Drawing.Bitmap
            Return GetImage(FileID, FilePath, MaxImageSize)
        End Function

        Private Function GetThumbImage() As System.Drawing.Bitmap
            Return GetImage(ThumbFileID, ThumbPath, MaxThumbSize)
        End Function

        Private Overloads Function GetImage(ByVal FileID As Integer, ByVal Filepath As String, ByVal NullImageSize As System.Drawing.Size) As System.Drawing.Bitmap
            Dim img As System.Drawing.Bitmap = Nothing
            Dim fs As Stream = Nothing
            Dim fc As New Services.FileSystem.FileController
            Dim fi As Services.FileSystem.FileInfo = Nothing

            Try
                If FileID <> -1 Then
                    fi = fc.GetFileById(FileID, PortalId)
                Else
                    If Not String.IsNullOrEmpty(Filepath) Then
                        Dim Folder As String = FileSystemUtils.FormatFolderPath(Path.GetDirectoryName(Filepath).Replace("\", "/"))
                        Dim FileName As String = Path.GetFileName(Filepath)
                        If Not String.IsNullOrEmpty(FileName) Then
                            Dim fldID As Integer = GetFolderIDFromName(Folder)
                            fi = fc.GetFile(FileName, PortalId, fldID)
                        End If
                    End If
                End If
                If Not fi Is Nothing Then
                    fs = FileSystemUtils.GetFileStream(fi) 'Handles InsecureFile, SecureFile and SecureDatabase folder types
                    img = ImageUtilities.LoadImage(fs)
                End If
            Finally
                If Not fs Is Nothing Then fs.Close()
                fs = Nothing
            End Try
            If img Is Nothing Then img = ImageUtilities.CreateBlankImage(NullImageSize, System.Drawing.Color.Black)
            Return img
        End Function

        Private Function GetImageSizeByFileID(ByVal FileID As Integer) As System.Drawing.Size
            If FileID <> -1 Then
                Dim fi As Services.FileSystem.FileInfo
                Dim fc As New Services.FileSystem.FileController
                fi = fc.GetFileById(FileID, PortalId)
                If Not fi Is Nothing Then
                    Return New System.Drawing.Size(fi.Width, fi.Height)
                End If
            End If
            Return (System.Drawing.Size.Empty)
        End Function

        Private Sub SetImageControlSizeByFileID(ByVal ctl As WebControls.Image, ByVal FileID As Integer)
            Dim sz As System.Drawing.Size = GetImageSizeByFileID(FileID)
            If Not ctl Is Nothing AndAlso Not sz.IsEmpty Then
                ctl.Width = Unit.Pixel(sz.Width)
                ctl.Height = Unit.Pixel(sz.Height)
            End If
        End Sub

        Private Function GetImageFromUri(ByVal uri As System.Uri) As System.Drawing.Bitmap
            Dim img As System.Drawing.Bitmap = Nothing
            Dim client As New System.Net.WebClient
            Dim bytes As Byte() = client.DownloadData(uri)
            If bytes.Length > 0 Then
                Dim dlStream As New MemoryStream(bytes)
                If AutoResize Then
                    img = ImageUtilities.CreateResizedImage(New System.Drawing.Bitmap(dlStream), _
                                                             MaxImageSize.Width, MaxImageSize.Height, _
                                                             LockAspect, MaxMagnification)
                Else
                    img = New System.Drawing.Bitmap(dlStream)
                End If
            End If
            If img Is Nothing Then img = ImageUtilities.CreateBlankImage(MaxImageSize, System.Drawing.Color.Black)
            Return img
        End Function

        'ViewState generic property get/set helpers

        Private Function GetPropertyValue(Of T)(ByVal PropertyName As String, ByVal DefaultValue As T) As T
            If ViewState(PropertyName) Is Nothing Then
                Return DefaultValue
            Else
                Return CType(ViewState(PropertyName), T)
            End If
        End Function

        Private Sub SetPropertyValue(Of T)(ByVal PropertyName As String, ByVal Value As T)
            ViewState(PropertyName) = Value
        End Sub
#End Region

    End Class

End Namespace